#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import subprocess

class CryptographyError(Exception):
    def __init__(self, errorCode, message):
        Exception.__init__(self, message)
        self.errorCode = errorCode

class Cryptography:
    def __init__(self, application="gpg", keyring=None):
        if keyring:
            self.base_args = [application, "--no-default-keyring", "--keyring", keyring]
        else:
            self.base_args = [application]
        try:
            self.__run_command(["--version"])
        except:
            raise CryptographyError(2, "Application '%s' was not found" % application)

    def verify_signature(self, signature_path, packet_path=""):
        if packet_path == "":
            return self.__run_command(["--verify", signature_path])
        else:
            return self.__run_command(["--verify", signature_path, packet_path])

    def create_signature(self, packet_path):
        return self.__run_command(["--armor", "--detach-sign", packet_path])

    def create_signature_by_default_keyring(self, packet_path, password):
        return self.__run_command(["--armor", "--detach-sign", "--batch", "--yes", "--passphrase", password, packet_path])

    def create_signature_by_keyring(self, packet_path, secret_keyring, password):
        return self.__run_command(["--armor", "--detach-sign", "--batch", "--yes", "--passphrase", password, "--secret-keyring", secret_keyring, packet_path])
        
    def import_public_key(self, key_name):
        return self.__run_command(["--import", key_name])

    def delete_public_key(self, key_id):
        return self.__run_command(["--batch", "--yes", "--delete-keys", key_id])

    def __run_command(self, args):
        process = subprocess.Popen(self.base_args + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
        process.communicate()
        retcode = process.wait()
        if retcode != 0:
            raise CryptographyError(retcode, "Execution failed")

        return True
